使用 Winston 实现分级日志收集
https://github.com/winstonjs/winston
日志库的必要性
- 传输通道
- Console 文件
- File 文件
- Http 通过http传输
- Stream 流传输
- 格式化
- 时间戳
- 格式美化
- 日志分割
- 按文件大小分割
- 按写入时间分割
- 日志分级
DEBUG
:调试,等级最低,一般生产环境会将该等级的日志关闭INFO
:信息,普通等级,最常用的系统日志收集等级,一般会将系统运行中的一些相关信息(非开发类敏感信息)设为该等级WARN
:FBI WARNNING大家都知道,就是警告,但又不到错误ERROR
:报错,一般程序报错使用该等级FATAL
:严重,比程序报错还严重的等级,如果没做错误等级划分的话,一般FATAL
都不怎么用到,都用ERROR
替代了
src/shared/logger.service.ts
import { Injectable, Scope } from '@nestjs/common';
import { createLogger, Logger, transports, format } from 'winston';
@Injectable({ scope: Scope.TRANSIENT })
export class AppLogger {
private context?: string;
private logger: Logger;
public setContext(context: string): void {
this.context = context;
}
constructor() {
this.logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.prettyPrint(),
),
transports: [
new transports.Console(),
new transports.File({ filename: 'logs/error.log', level: 'error' }),
new transports.File({ filename: 'logs/combined.log' }),
],
});
}
error(
ctx: any,
message: string,
meta?: Record<string, any>,
): Logger {
return this.logger.error({
message,
contextName: this.context,
ctx,
...meta,
});
}
warn(
ctx: any,
message: string,
meta?: Record<string, any>,
): Logger {
return this.logger.warn({
message,
contextName: this.context,
ctx,
...meta,
});
}
debug(
ctx: any,
message: string,
meta?: Record<string, any>,
): Logger {
return this.logger.debug({
message,
contextName: this.context,
ctx,
...meta,
});
}
verbose(
ctx: any,
message: string,
meta?: Record<string, any>,
): Logger {
return this.logger.verbose({
message,
contextName: this.context,
ctx,
...meta,
});
}
log(
ctx: any,
message: string,
meta?: Record<string, any>,
): Logger {
return this.logger.info({
message,
contextName: this.context,
ctx,
...meta,
});
}
}
/src/shared/logger/logger.module.ts
import { Module } from '@nestjs/common';
import { AppLogger } from './logger.service';
@Module({
imports: [],
providers: [AppLogger],
exports: [AppLogger],
})
export class AppLoggerModule { }
src/shared/logger.service.ts
@Module({
imports: [
AppLoggerModule,
],
exports: [
AppLoggerModule,
],
})
export class SharedModule { }
测试
src/user/services/auth.services.ts
@Injectable()
export class AuthService {
constructor(
private readonly logger: AppLogger,
){
this.logger.setContext(AuthService.name);
}
/**
* 获取短信验证码
* @param mobile
*/
async login(dto: RegisterCodeDTO) {
this.logger.log(null, 'Login...')
}
}